package com.example.esp8266_wifi_control;

import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiNetworkSuggestion;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.esp8266_wifi_control.utils.SocketUtil;

import com.example.esp8266_wifi_control.utils.WifiUtil;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity implements SocketUtil.MessageCallback {

    private static final String TAG = "MainActivity";
    private WifiUtil wifiUtils;

    private static final int NOT_NOTICE = 2;//如果勾选了不再询问
    private AlertDialog alertDialog;
    private AlertDialog mDialog;

    private static final String SSID = "nodemcu123";
    private static final String PWD = "nodemcu123";

    private SocketUtil socketUtil;

    @BindView(R.id.logView)
    TextView logView;
    @BindView(R.id.send_text_edit)
    EditText sendEditText;
    @BindView(R.id.broadcastBtn)
    Button startBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initUtils();
    }

    public void initUtils() {
        myRequestPermission();
        wifiUtils = new WifiUtil(this);
        socketUtil = new SocketUtil(this);
    }

    public void initView() {
        ButterKnife.bind(this);
        logView.setMovementMethod(new ScrollingMovementMethod());
    }

    @OnClick(R.id.scan_wifi_btn)
    public void scanWifiClick() {
        wifiUtils.openWifi();
        Log.i(TAG, "scan_wifi_btn clicked; ");
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            if (!wifiUtils.wifiIsEnable()) {
                startActivity(new Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY));
            }
            wifiConnect(SSID, PWD);
        } else {
            if (!wifiUtils.wifiIsEnable()) {
                wifiUtils.openWifi();
            }
            wifiUtils.startScan();
            List<ScanResult> results = wifiUtils.getWifiList();
            for (ScanResult result : results) {
                Log.i(TAG, "wifi: " + result.SSID);
                if (result.SSID.startsWith(SSID)) {
                    Log.i(TAG, "connect: " + result.SSID + " " + result.capabilities);
                    boolean connect = wifiUtils.addNetWork(result.SSID, PWD, 3);
                    if (connect) {
                        Toast.makeText(this, "WIFI连接成功！", Toast.LENGTH_SHORT).show();
                        Log.i(TAG, "WIFI连接成功: " + wifiUtils.getIPAddress());
                        startConn();
                    } else {
                        Toast.makeText(this, "WIFI连接失败！", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

    @OnClick(R.id.send_btn)
    public void sendClick() {
        this.showLog(sendEditText.getText().toString());
        new Thread(() -> {
            socketUtil.send(sendEditText.getText().toString(), MainActivity.this);
        }).start();
    }

    @OnClick(R.id.cleanLog)
    public void cleanLog() {
        this.logView.setText("");
        offsetLogview();
    }

    private int start = 0;

    @OnClick(R.id.broadcastBtn)
    public void broadcastClick() {
        this.showLog(sendEditText.getText().toString());
        String msg = "1";
        if (start != 0) {
            msg = "0";
            start = 0;
        } else {
            start = 1;
        }
        String finalMsg = msg;
        Log.i(TAG, "broadcastClick: " + msg + "___" + start);
        new Thread(() -> {
            socketUtil.send(finalMsg, MainActivity.this);
        }).start();
        startBtn.setText(start == 1 ? "停止" : "开始");
    }

    public void startConn() {
        new Thread(() -> {
            String ip = getIP(MainActivity.this);
            String ips[] = ip.split("\\.");
            if (ips.length != 4) {
                showLog("ip error:" + ip);
                return;
            }
            socketUtil.initTcpSocket(String.format("%s.%s.%s.1", ips[0], ips[1], ips[2]), 8888);
        }).start();
    }

    private void myRequestPermission() {
        List<String> permission = new ArrayList<>();
        permission.add(Manifest.permission.CHANGE_NETWORK_STATE);
        permission.add(Manifest.permission.CHANGE_WIFI_STATE);
        permission.add(Manifest.permission.ACCESS_NETWORK_STATE);
        permission.add(Manifest.permission.ACCESS_WIFI_STATE);
        permission.add(Manifest.permission.INTERNET);
        permission.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        permission.add(Manifest.permission.ACCESS_FINE_LOCATION);
        for (String s : permission) {
            if (ContextCompat.checkSelfPermission(this, s) != PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{s}, 1);
            } else {
                Toast.makeText(this, "您已经申请了权限!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PERMISSION_GRANTED) {//选择了“始终允许”
                    Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
                } else {
                    Log.i(TAG, "onRequestPermissionsResult: " + permissions[i]);
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {//用户选择了禁止不再询问
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("permission")
                                .setMessage("点击允许才可以使用我们的app哦")
                                .setPositiveButton("去允许", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        if (mDialog != null && mDialog.isShowing()) {
                                            mDialog.dismiss();
                                        }
                                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                        Uri uri = Uri.fromParts("package", getPackageName(), null);//注意就是"package",不用改成自己的包名
                                        intent.setData(uri);
                                        startActivityForResult(intent, NOT_NOTICE);
                                    }
                                });
                        mDialog = builder.create();
                        mDialog.setCanceledOnTouchOutside(false);
                        mDialog.show();


                    } else {//选择禁止
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("permission")
                                .setMessage("点击允许才可以使用我们的app哦")
                                .setPositiveButton("去允许", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        if (alertDialog != null && alertDialog.isShowing()) {
                                            alertDialog.dismiss();
                                        }
                                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                                    }
                                });
                        alertDialog = builder.create();
                        alertDialog.setCanceledOnTouchOutside(false);
                        alertDialog.show();
                    }

                }
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public void wifiConnect(String ssid, String pwd) {
        WifiNetworkSuggestion.Builder builder2 = new WifiNetworkSuggestion.Builder()
                .setSsid(ssid)
                .setWpa2Passphrase(pwd);
        WifiNetworkSuggestion suggestion = builder2.build();

        ArrayList<WifiNetworkSuggestion> list = new ArrayList<>();
        list.add(suggestion);

        WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        int status = manager.addNetworkSuggestions(list);

        if (status == STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
            //We have successfully added our wifi for the system to consider
            Log.i(TAG, "STATUS_NETWORK_SUGGESTIONS_SUCCESS ");
            WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
            builder.setSsid(ssid);
            builder.setWpa2Passphrase(pwd);

            WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();

            NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
            networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
            networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);

            NetworkRequest nr = networkRequestBuilder1.build();
            ConnectivityManager cm = (ConnectivityManager)
                    getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            ConnectivityManager.NetworkCallback networkCallback = new
                    ConnectivityManager.NetworkCallback() {
                        @Override
                        public void onAvailable(Network network) {
                            super.onAvailable(network);
                            Log.d(TAG, "onAvailable:" + network);
                            boolean flag = cm.bindProcessToNetwork(network);
                            if (flag) {
                                Log.i(TAG, "WIFI连接成功: " + wifiUtils.getIPAddress());
                                startConn();
                            } else {
                                Log.i(TAG, "onAvailable: bindProcessToNetwork false");
                            }
                        }
                    };
            cm.requestNetwork(nr, networkCallback);
        } else {
            Log.i(TAG, "test: " + status);
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == NOT_NOTICE) {
            myRequestPermission();//由于不知道是否选择了允许所以需要再次判断
        }
    }

    public void showLog(String result) {
        logView.append(result + "\n");
        offsetLogview();
    }

    private void offsetLogview() {
        int offset = (logView.getLineCount() + 1) * logView.getLineHeight();
        if (offset > logView.getHeight()) {
            if (Looper.myLooper() == Looper.getMainLooper()) {
                logView.scrollTo(0, offset - logView.getHeight());
            } else {
                runOnUiThread(() -> logView.scrollTo(0, offset - logView.getHeight()));
            }
        }
    }

    @Override
    public void handler(String remoteAddress, String msg) {
        showLog("msg:" + msg);
    }

    public static String getIP(Context context) {
        String ip = "0.0.0.0";
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        int type = info.getType();

        return getWifiIP(context);
    }

    /**
     * 获取wifiIP地址
     *
     * @param context
     * @return
     */
    public static String getWifiIP(Context context) {
        android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) context
                .getSystemService(android.content.Context.WIFI_SERVICE);
        WifiInfo wifiinfo = wifi.getConnectionInfo();
        int intaddr = wifiinfo.getIpAddress();
        byte[] byteaddr = new byte[]{(byte) (intaddr & 0xff),
                (byte) (intaddr >> 8 & 0xff), (byte) (intaddr >> 16 & 0xff),
                (byte) (intaddr >> 24 & 0xff)};
        InetAddress addr = null;
        try {
            addr = InetAddress.getByAddress(byteaddr);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        String mobileIp = addr.getHostAddress();
        return mobileIp;
    }


    @Override
    public void udpMsg(String msg) {
        showLog("udp:" + msg);
    }
}